package com.dingding.special.order.appoint.dao.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.dingding.common.core.base.daox.IBaseDaoX;
import com.dingding.common.core.base.daox.ISQLBaseDao;
import com.dingding.common.core.beans.UserTaxiOrdert;
import com.dingding.common.core.beans.special.UserspecialorderT;
import com.dingding.common.core.push.factory.dtos.OrderDurationDTO;
import com.dingding.common.core.push.factory.dtos.OrderDurationPara;
import com.dingding.common.core.util.amap.AmapApi;
import com.dingding.special.common.exception.bussiness.BizExpEnum;
import com.dingding.special.common.exception.bussiness.BussinessException;
import com.dingding.special.common.exception.server.ServerException;
import com.dingding.special.common.exception.server.ServerExpEnum;
import com.dingding.special.order.appoint.dao.IAppointDao;
import com.dingding.special.user.driver.dto.onlinedriver.OLineDriverDto;

@Component("appointDao")
public class AppointDaoImpl implements IAppointDao {

	private Logger log = Logger.getLogger(this.getClass());

	@Resource(name = "baseDaoX")
	IBaseDaoX baseDaoX;

	@Resource(name = "SQLBaseDao")
	ISQLBaseDao sqlBaseDao;

	@Override
	public OrderDurationDTO getOrderDuration(OrderDurationPara para) {
		try {
			BigDecimal distance = AmapApi.getTwoPointDistance(para.getStartLng(), para.getStartLat(), para.getEndLng(),
					para.getEndLat()); // 订单里程
			int duration = AmapApi.getOriginsToDestinationFastestTime(para.getStartLng() + "," + para.getStartLat(),
					para.getEndLng() + "," + para.getEndLat()); // 订单时长
			BigDecimal startDistance = AmapApi.getTwoPointDistance(para.getStartLng(), para.getStartLat(),
					para.getDriverLng(), para.getDriverLat()); // 司机距离出发地距离

			OrderDurationDTO dto = new OrderDurationDTO();
			dto.setDistance(distance);
			dto.setDuration(duration);
			dto.setStartDistance(startDistance);
			return dto;
		} catch (Exception e) {
			log.error("查询订单距离时候出现错误！AppointDaoImpl ：getOrderDuration()", e);
			throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
		}
	}

	@Override
	public OrderDurationDTO getOrderDuration(OLineDriverDto driver, UserspecialorderT orderT) {

		OrderDurationPara para = new OrderDurationPara();
		para.setDriverLat(driver.getLatitude());
		para.setDriverLng(driver.getLongitude());
		para.setStartLat(orderT.getStartLatitude());
		para.setStartLng(orderT.getStartLongitude());
		para.setEndLat(orderT.getEndLatitude());
		para.setEndLng(orderT.getEndLongitude());
		OrderDurationDTO orderDurationDTO = this.getOrderDuration(para);
		return orderDurationDTO;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public UserspecialorderT getUserSpecialOrderById(String specialOrderId) {
		UserspecialorderT orderT = null;
		try {
			orderT = baseDaoX.getById(specialOrderId, UserspecialorderT.class);
		} catch (Exception e) {
			log.error("修改订单状态错误！AppointDaoImpl ：changeOrderStatus()", e);
			throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
		}
		if (orderT == null) {
			throw new BussinessException(BizExpEnum.NO_THIS_ORDER);
		}
		return orderT;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void changeOrderStatus(UserspecialorderT userspecialorderT, int status) {
		UserspecialorderT orderT = getUserSpecialOrderById(userspecialorderT.getSpecialOrderId());
		orderT.setOrderStatus(status);// 1:待指派 2:待上车(已指派) 3:已上车 4:待支付(已到达) 5:已完成
										// 6:已取消
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void afterPushToDriver(String userSpecialOrderId, String driverId) {
		UserspecialorderT orderT = getUserSpecialOrderById(userSpecialOrderId);
		orderT.setGrabOrderUserId(driverId);
		orderT.setOrderStatus(2);// 1:待指派 2:待上车(已指派) 3:已上车 4:待支付(已到达) 5:已完成
									// 6:已取消
		orderT.setAppointTime(new Date());
	}

	@Override
	@Transactional(readOnly = true)
	public int getSpecialOrderStatus(String specialOrderId) {
		try {
			return this.getUserSpecialOrderById(specialOrderId).getOrderStatus();
		} catch (Exception e) {
			return -1;// 订单不存在，返回错误码
		}
	}

	@Override
	@Transactional(readOnly = true)
	public boolean isDriverOrdering(String driverId) {
		try {
			List<UserspecialorderT> list = this.sqlBaseDao.listSqlToCustomBean(UserspecialorderT.class,
					"SELECT * FROM userspecialordert ot WHERE ot.grabOrderUserId = ? AND ot.orderStatus IN (2,3)",
					driverId);

			if (list == null || list.size() == 0) {
				return false;
			} else {
				return true;
			}
		} catch (Exception e) {
			log.error("查询司机是否有进行中订单时候报错！AppointDaoImpl : isDriverOrdering()", e);
			throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
		}
	}

	@Override
	@Transactional(readOnly = true)
	public boolean isDriverHaveUnRealOrder(String driverId) {
		try {
			List<UserspecialorderT> list = this.sqlBaseDao.listSqlToCustomBean(UserspecialorderT.class,
					"SELECT * FROM userspecialordert ot WHERE ot.grabOrderUserId = ? AND ot.setOutType = 2 AND ot.orderStatus IN (2,3)", driverId);

			if (list == null || list.size() == 0) {
				return false;
			} else {
				return true;
			}
		} catch (Exception e) {
			log.error("查询司机是否有预约订单时候报错！AppointDaoImpl : isDriverHaveUnRealOrder()", e);
			throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
		}
	}

	/**
	 * @Description 获取出租车订单的状态
	 * @param orderId 订单id
	 * @author fengshuonan
	 * @return int 1：待抢单   2：服务中    3：待支付     4：已完成      5：已取消
	 */
	@Override
	public int getTaxiOrderStatus(String orderId) {
		try {
			UserTaxiOrdert ordert = this.baseDaoX.getById(orderId, UserTaxiOrdert.class);
			if(ordert == null){
				return -1;
			}else{
				return ordert.getOrderStatus();
			}
		} catch (Exception e) {
			log.error("查询出租车订单出错！AppointDaoImpl : getTaxiOrderStatus()",e);
			return -1;
		}
	}

	@Override
	@Transactional(readOnly = true)
	public boolean isDriverHaveTaxiOrder(String userId) {
		try {
			List<UserTaxiOrdert> list = this.sqlBaseDao.listSqlToCustomBean(UserTaxiOrdert.class,
					"SELECT * FROM usertaxiordert ot WHERE ot.grabOrderUserId = ? AND ot.orderStatus IN (2,3)",userId);
			if (list == null || list.size() == 0) {
				return false;
			} else {
				return true;
			}
		} catch (Exception e) {
			log.error("查询司机是否有进行中订单时候报错！AppointDaoImpl : isDriverOrdering()", e);
			return true;
		}
	}

	/**
	 * @Description 获取出租车的订单里程信息
	 * @param dto 在线司机的信息
	 * @param taxiOrdert 出租车订单
	 * @author fengshuonan
	 * @return OrderDurationDTO 订单里程信息
	 */
	@Override
	public OrderDurationDTO getTaxiOrderDuration(OLineDriverDto dto, UserTaxiOrdert taxiOrdert) {
		OrderDurationPara para = new OrderDurationPara();
		para.setDriverLat(dto.getLatitude());
		para.setDriverLng(dto.getLongitude());
		para.setStartLat(taxiOrdert.getStartLatitude());
		para.setStartLng(taxiOrdert.getStartLongitude());
		para.setEndLat(taxiOrdert.getEndLatitude());
		para.setEndLng(taxiOrdert.getEndLongitude());
		OrderDurationDTO orderDurationDTO = this.getOrderDuration(para);
		return orderDurationDTO;
	}
}
